const path = require('path');
// 打包时清除dist
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 打包时不生成LICENSE.txt
const TerserPlugin = require('terser-webpack-plugin');
// 将css单独打包的插件，用于替代 style-loader插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// Webpack-dev-server的使用：引入webpack全局变量
const webpack = require('webpack');

var getHtmlConfig = function(name) {
  return {
    template: './src/view/' + name + '.html', // 指定打包的文件的来源（位置）
    filename: 'view/' + name + '.html', // 指定打包后的保存位置，不能用[name]这种方式传值
    // inject注入：自动识别引用的资源并注入，不需要另外在页面内引用，类似Spring IoC
    // 比如每次打包前在js中被引用了的东西，都无需在html中手动引用，打包后自动会在结果中（html中）生成引用
    inject  : true, 
    hash    : true, // 给个哈希值（版本号）进行文件的版本匹配
    chunks  : ['common', name], // 指定与之相关的入口，common的全局用法
    minify  : { // 指定不进行代码压缩
      collapseWhitespace : false
    }
  }
}

var config = {
  entry: { // 多页应用入口
    'index': ['./src/page/index/index.js'],
    'login': ['./src/page/login/index.js'],
    'common': ['./src/page/common/index.js'],
  },
  plugins: [ // 不是自带的插件都需要new出来
      // 每个正经的.html都需要new出一个HtmlWebpackPlugin，但是工具类.htm使用html-loader就可
      new HtmlWebpackPlugin(getHtmlConfig('index')),
      new HtmlWebpackPlugin(getHtmlConfig('login')),
      new MiniCssExtractPlugin({
        filename: 'css/[name].css' // 指定dist目录下的css目录为保存位置
      }),
      new webpack.HotModuleReplacementPlugin(), // 开启热替换
  ],
  output: {
    filename: 'js/[name].js', // 设置最后打包生成的js文件名字
    path: path.resolve(__dirname, 'dist'), // 设置打包之后生成文件保存的路径
    clean: true , // 设置每次打包都对生成路径下的dist文件夹进行清除
  },
  devServer: {
    port: 8888, // 设定localhost的端口
    contentBase: path.resolve(__dirname, 'dist'), // 指定启动后打开的目录（部署的目录）为dist
  },
  optimization: { // LICENSE.txt的清除
    minimize : false, // 不将打包之后的js代码压缩
    minimizer : [
      new TerserPlugin({
          extractComments: false, // 不将注释提取到单独的文件当中
      })
    ],
    splitChunks   : { // 公共模块代码的提取
      cacheGroups : { // 使用缓存组提高加载效率
        commons   : { // commons是对自己写的公共代码进行配置
          name        : 'util', // 指定公共代码被打包之后的文件名
          chunks      : 'all',  // 指定需要被处理的代码类型
          minChunks   : 2, // 至少被2个及以上文件引用的代码则独立出来（被认为是公共部分）
          minSize     : 0 // 公共部分过小就不独立（而是直接挨个复制过去），这里不论公共部分多大都独立出来
        },
        vendors   : {} // 公共插件
      }
    }
  },
  externals: {
    // 网页中一旦引用了jq（script方式），那么webpack中也可以通过require引用作为外部变量，但是jq名字不能为$
    'jquery': 'window.jQuery', 
  },
  module: {
    rules: [
      {// css打包参数
        test: /\.css$/, // 测试：指定对.css结尾的文件进行处理
        use : [
          {
            loader : MiniCssExtractPlugin.loader,
            options: {
              publicPath : '../' // 指定css生成位置的路径
            }
          },
          'css-loader'
        ]
      },
      { // 图片的打包处理
        test: /\.(png|svg|jpg|gif)$/,
        // name=images/[name].[ext]指定在生成目录下新建一个images目录然后将1000Byte大小以上的图片写入[name].[ext]
        // url-loader专门处理css中图片的引用，其他的地方使用file-loader，用法类似
        use : {
          loader  : 'url-loader',
          options : {
            name      : 'images/[name].[ext]',
            limit     : 10,
            esModule  : false
          }
        }
      },
      {// 工具类htm打包参数
        test: /\.htm$/, // 测试：指定对.htm结尾的文件进行处理
        use : [
          {
            loader : 'html-loader',
            options: {
              esModule  : false, // 加载时当成es6的对象进行加载，这里将htm的代替部分原封不动进行复制
              minimize  : false
            }
          }
        ]
      }
    ]
  },
  resolve : {
    alias : { // 定义别名
      util          : __dirname + '/src/util',
      page          : __dirname + '/src/page',
      images        : __dirname + '/src/images',
      service       : __dirname + '/src/service',
      node_modules  : __dirname + '/node_modules',
    }
  }
};

module.exports = config;